package cn.demoncat.util.web.aspect;

import cn.demoncat.util.io.CloseUtil;
import cn.demoncat.util.lang.JsonUtil;
import cn.demoncat.util.lang.constant.CharsetConstant;
import cn.demoncat.util.lang.entity.Result;
import cn.demoncat.util.web.util.ExceptionHandlerUtil;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 描述：全局统一异常处理器AOP
 *
 * 1、拦截@Controller和@RestController注解的类
 * 2、适用于混合Html和JSON返回值的Controller
 * 3、所有异常输出Log日志，并转换为Result，返回error.html或JSON(类注解@RestController、方法注解@ResponseBody)
 * 
 * 注：本类废弃，统一使用前后端分离项目，即使用RestGlobalExceptionHandler处理异常
 * 
 * @author 延晓磊
 *
 * @since 2017年7月21日
 */
//@ControllerAdvice
public class GlobalExceptionHandler {
	
	/**
	 * 异常处理器：Controller发生异常时拦截
	 * 
	 * @param request	
	 * @param response	
	 * @param handler	方法
	 * @param ex		异常
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2018年4月11日
	 */
	@ExceptionHandler
	public ModelAndView exceptionHandler(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, Exception ex){
		// 处理异常
		Result error = ExceptionHandlerUtil.handle(ex, true);
		
		// 判断是否为JSON请求 - Controller类注解 @RestController
		boolean isAjax = handler.getBeanType().isAnnotationPresent(RestController.class);
		// 判断是否为JSON请求 - Handler方法注解@ResponseBody
		if (!isAjax) {
			isAjax = handler.getMethod().isAnnotationPresent(ResponseBody.class);
		}
 
		if (isAjax) {
			// 设置响应头
			response.setStatus(HttpStatus.OK.value());
			response.setContentType(MediaType.APPLICATION_JSON_VALUE); 
			response.setCharacterEncoding(CharsetConstant.UTF8);
			// 输出JSON
			PrintWriter writer = null;
			try {
				writer = response.getWriter();
				writer.write(JsonUtil.toStr(error));
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				CloseUtil.close(writer);
			}
			return null;
		}else{
			// 根据错误状态，分发到不同的错误页面
			ModelAndView mv = new ModelAndView();
			mv.addObject("error", error);
			mv.setViewName(Result.ERROR_PAGE.get(error.getStatus()));
			return mv;
		}
	}
	 
}
